package org.jeecg.modules.zcgl.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.constant.CacheConstant;
import org.jeecg.common.constant.FillRuleConstant;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.FillRuleUtil;
import org.jeecg.modules.zcgl.entity.Region;
import org.jeecg.modules.zcgl.entity.RegionUser;
import org.jeecg.modules.zcgl.mapper.RegionMapper;
import org.jeecg.modules.zcgl.mapper.RegionUserMapper;
import org.jeecg.modules.zcgl.service.IRegionService;
import org.jeecg.modules.zcgl.util.FindsRegionChildrenUtil;
import org.jeecg.modules.zcgl.vo.RegionIdModel;
import org.jeecg.modules.zcgl.vo.RegionTreeModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description: 区域信息
 * @Author: jeecg-boot
 * @Date: 2020-08-11
 * @Version: V1.0
 */
@Service
public class RegionServiceImpl extends ServiceImpl<RegionMapper, Region> implements IRegionService {

    @Autowired
    private RegionUserMapper regionUserMapper;

    @Override
    public List<RegionTreeModel> queryMyRegionTreeList(Map<String, Object> par) {
        LoginUser user = JwtUtil.getLoginUser();
        par.put("userId", user.getId());
        List<Region> list = this.queryMyRegionList(par);
        List<RegionTreeModel> listResult = FindsRegionChildrenUtil.wrapTreeDataToTreeList(list);
        return listResult;
    }

    @Override
    @Cacheable(value = CacheConstant.ZCGL_MY_REGION_CACHE + "':'#userId")
    public List<Region> queryMyRegionList(String userId) {
        Map<String, Object> par = new HashMap<>();
        par.put("userId", userId);
        return this.queryMyRegionList(par);
    }

    @Override
    public List<String> queryMyRegionIdList(String userId) {
        List<String> re = new ArrayList<>();
        List<Region> list = this.queryMyRegionList(userId);
        if (list != null){
            for (Region region : list) {
                re.add(region.getId());
            }
        }
        return re;
    }

    /**
     * 根据条件查询列表
     * @param par
     * @return
     */
    private List<Region> queryMyRegionList(Map<String, Object> par) {
        List<Region> list = baseMapper.listByUserId(par);
        if (list == null || list.size() == 0) {
            return new ArrayList<>();
        }
        LambdaQueryWrapper<Region> query = new LambdaQueryWrapper<>();
        for (Region region : list) {
            query.or().likeRight(Region::getRegionCode, region.getRegionCode());
        }
        query.orderByAsc(Region::getRegionOrder);
        return this.list(query);
    }


    @Override
//    @Cacheable(value = CacheConstant.ZCGL_MY_REGION_CACHE)
    public List<RegionTreeModel> queryMyRegionTreeList() {
        LoginUser user = JwtUtil.getLoginUser();
        List<Region> list = this.queryMyRegionList(user.getId());
        List<RegionTreeModel> listResult = FindsRegionChildrenUtil.wrapTreeDataToTreeList(list);
        return listResult;
    }

    @Override
    @Cacheable(value = CacheConstant.ZCGL_REGION_CACHE)
    public List<RegionTreeModel> queryTreeList() {
        LambdaQueryWrapper<Region> query = new LambdaQueryWrapper<Region>();
//		query.eq(Region::getDelFlag, CommonConstant.DEL_FLAG_0.toString());
        query.orderByAsc(Region::getRegionOrder);
        List<Region> list = this.list(query);
        // 调用wrapTreeDataToTreeList方法生成树状数据
        List<RegionTreeModel> listResult = FindsRegionChildrenUtil.wrapTreeDataToTreeList(list);
        return listResult;
    }

    @Cacheable(value = CacheConstant.ZCGL_REGION_IDS_CACHE)
    @Override
    public List<RegionIdModel> queryRegionIdTreeList() {
        LambdaQueryWrapper<Region> query = new LambdaQueryWrapper<Region>();
        query.orderByAsc(Region::getRegionOrder);
        List<Region> list = this.list(query);
        // 调用wrapTreeDataToTreeList方法生成树状数据
        List<RegionIdModel> listResult = FindsRegionChildrenUtil.wrapTreeDataToRegionIdTreeList(list);
        return listResult;
    }

    @Override
    @Transactional
    public boolean saveRegionData(Region region) {

        //检测实体
        this.checkModel(region);

        // 先判断该对象有无父级ID,有则意味着不是最高级,否则意味着是最高级
        // 获取父级ID
        String parentId = region.getParentId();
        JSONObject formData = new JSONObject();
        formData.put("parentId", parentId);
        Object o = FillRuleUtil.executeRule(FillRuleConstant.REGION, formData);
        String code = o == null ? "" : o.toString();
        region.setRegionCode(code);
        return this.save(region);
    }


    /**
     * 检测实体验证
     *
     * @param region
     */
    private void checkModel(Region region) {
        if (region == null) {
            throw new JeecgBootException("区域信息不能为空！");
        }
        if (region.getParentId() == null) {
            region.setParentId("");
        }
        LambdaQueryWrapper<Region> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Region::getParentId, region.getParentId());
        if (StringUtils.isNotBlank(region.getId())) {
            queryWrapper.ne(Region::getId, region.getId());
        }
        queryWrapper.eq(Region::getRegionName, region.getRegionName());
        queryWrapper.last("LIMIT 1");
        Region a = baseMapper.selectOne(queryWrapper);
        if (a != null) {
            throw new JeecgBootException("【" + region.getRegionName() + "】区域已存在");
        }
    }

    @Override
    public Boolean updateRegionDataById(Region region) {
        this.checkModel(region);

        return this.updateById(region);
    }

    @Override
    public List<RegionTreeModel> searhBy(String keyWord, String myRegionSearch, String regionIds) {
        return null;
    }


    /**
     * 根据区域id删除并且删除其可能存在的子级任何区域
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(String id) {
        List<String> idList = new ArrayList<>();
        idList.add(id);
        return this.deleteBatchWithChildren(idList);
    }

    @Override
    public List<Region> queryUserRegions(String userId) {
        return null;
    }

    @Override
    public List<Region> queryRegionsByUsername(String username) {
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteBatchWithChildren(List<String> ids) {
        List<String> idList = new ArrayList<>();
        for (String id : ids) {
            idList.add(id);
            this.checkChildrenExists(id, idList);
        }
        boolean ok = this.removeByIds(idList);
        if (ok) {
            regionUserMapper.delete(new LambdaQueryWrapper<RegionUser>().in(RegionUser::getRegionId, idList));
        }
        return ok;
    }

    @Override
    public List<String> getSubDepIdsByDepId(String regionId) {
        return null;
    }

    @Override
    public List<String> getMySubDepIdsByDepId(String regionIds) {
        return null;
    }


    /**
     * delete 方法调用
     *
     * @param id
     * @param idList
     */
    private void checkChildrenExists(String id, List<String> idList) {
        LambdaQueryWrapper<Region> query = new LambdaQueryWrapper<Region>();
        query.eq(Region::getParentId, id);
        List<Region> regionList = this.list(query);
        if (regionList != null && regionList.size() > 0) {
            for (Region region : regionList) {
                idList.add(region.getId());
                this.checkChildrenExists(region.getId(), idList);
            }
        }
    }

}
